pyGdbToolkit 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyGdbToolkit/__init__.py +55 -0
- pyGdbToolkit/arch/__init__.py +79 -0
- pyGdbToolkit/arch/arm/__init__.py +17 -0
- pyGdbToolkit/arch/arm/coresight.py +427 -0
- pyGdbToolkit/arch/arm/cortex_m.py +504 -0
- pyGdbToolkit/arch/arm/fault.py +629 -0
- pyGdbToolkit/arch/arm/models.py +60 -0
- pyGdbToolkit/arch/arm/mpu.py +556 -0
- pyGdbToolkit/arch/arm/probe.py +10 -0
- pyGdbToolkit/arch/arm/providers/__init__.py +16 -0
- pyGdbToolkit/arch/arm/providers/base.py +77 -0
- pyGdbToolkit/arch/arm/providers/manufacturers/__init__.py +4 -0
- pyGdbToolkit/arch/arm/providers/manufacturers/stm32.py +680 -0
- pyGdbToolkit/arch/arm/sau.py +253 -0
- pyGdbToolkit/arch/arm/security.py +816 -0
- pyGdbToolkit/arch/arm/session_state.py +96 -0
- pyGdbToolkit/arch/arm/target.py +32 -0
- pyGdbToolkit/arch/base.py +143 -0
- pyGdbToolkit/arch/diagnostics.py +300 -0
- pyGdbToolkit/arch/registry.py +43 -0
- pyGdbToolkit/cmd_faultinfo.py +99 -0
- pyGdbToolkit/cmd_lscpu.py +116 -0
- pyGdbToolkit/cmd_profile.py +1402 -0
- pyGdbToolkit/cmd_rtos.py +298 -0
- pyGdbToolkit/cmd_secscan.py +466 -0
- pyGdbToolkit/cmd_svd.py +1208 -0
- pyGdbToolkit/diagnostic_runtime.py +52 -0
- pyGdbToolkit/rtos/__init__.py +8 -0
- pyGdbToolkit/rtos/camelot.py +513 -0
- pyGdbToolkit/session.py +233 -0
- pyGdbToolkit/svd.py +1194 -0
- pyGdbToolkit/target_memory.py +190 -0
- pygdbtoolkit-0.1.0.dist-info/METADATA +586 -0
- pygdbtoolkit-0.1.0.dist-info/RECORD +36 -0
- pygdbtoolkit-0.1.0.dist-info/WHEEL +5 -0
- pygdbtoolkit-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 H2Lab Development Team
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""Typed target-memory access shared by GDB commands."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import Protocol, runtime_checkable
|
|
9
|
+
|
|
10
|
+
import gdb
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TargetMemory(Protocol):
|
|
14
|
+
"""The integer-oriented target-memory operations used by providers."""
|
|
15
|
+
|
|
16
|
+
def read_bytes(self, address: int, size: int) -> bytes:
|
|
17
|
+
"""Read an exact number of bytes from target memory."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def read_uint16(self, address: int) -> int:
|
|
21
|
+
"""Read a little-endian unsigned 16-bit integer."""
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
def read_uint32(self, address: int) -> int:
|
|
25
|
+
"""Read a little-endian unsigned 32-bit integer."""
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@runtime_checkable
|
|
30
|
+
class WritableTargetMemory(TargetMemory, Protocol):
|
|
31
|
+
"""Target-memory operations that can also write 32-bit register values."""
|
|
32
|
+
|
|
33
|
+
def write_uint32(self, address: int, value: int) -> None:
|
|
34
|
+
"""Write a little-endian unsigned 32-bit integer."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TargetReadError(RuntimeError):
|
|
39
|
+
"""An error enriched with the target-memory range that could not be read."""
|
|
40
|
+
|
|
41
|
+
def __init__(self, address: int, size: int, reason: str) -> None:
|
|
42
|
+
"""Initialize an error for one failed target-memory operation.
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
address
|
|
47
|
+
First target address that was requested.
|
|
48
|
+
size
|
|
49
|
+
Number of bytes requested.
|
|
50
|
+
reason
|
|
51
|
+
The underlying target-access failure.
|
|
52
|
+
"""
|
|
53
|
+
self.address = address
|
|
54
|
+
self.size = size
|
|
55
|
+
self.reason = reason
|
|
56
|
+
super().__init__(f"could not read {size} byte(s) at 0x{address:08X}: {reason}")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class TargetWriteError(RuntimeError):
|
|
60
|
+
"""An error enriched with the target-memory range that could not be written."""
|
|
61
|
+
|
|
62
|
+
def __init__(self, address: int, size: int, reason: str) -> None:
|
|
63
|
+
"""Initialize an error for one failed target-memory write.
|
|
64
|
+
|
|
65
|
+
Parameters
|
|
66
|
+
----------
|
|
67
|
+
address
|
|
68
|
+
First target address that was requested.
|
|
69
|
+
size
|
|
70
|
+
Number of bytes requested.
|
|
71
|
+
reason
|
|
72
|
+
The underlying target-access failure.
|
|
73
|
+
"""
|
|
74
|
+
self.address = address
|
|
75
|
+
self.size = size
|
|
76
|
+
self.reason = reason
|
|
77
|
+
super().__init__(f"could not write {size} byte(s) at 0x{address:08X}: {reason}")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class TargetMemoryReader:
|
|
81
|
+
"""Read little-endian values from GDB's selected inferior."""
|
|
82
|
+
|
|
83
|
+
def __init__(self, inferior: gdb.Inferior | None = None) -> None:
|
|
84
|
+
"""Create a reader for an inferior.
|
|
85
|
+
|
|
86
|
+
Parameters
|
|
87
|
+
----------
|
|
88
|
+
inferior
|
|
89
|
+
An optional GDB inferior. The selected inferior is used by default.
|
|
90
|
+
"""
|
|
91
|
+
if inferior is not None:
|
|
92
|
+
self._inferior = inferior
|
|
93
|
+
return
|
|
94
|
+
try:
|
|
95
|
+
self._inferior = gdb.selected_inferior()
|
|
96
|
+
except gdb.error as error:
|
|
97
|
+
raise TargetReadError(0, 0, f"could not select inferior: {error}") from error
|
|
98
|
+
|
|
99
|
+
def read_bytes(self, address: int, size: int) -> bytes:
|
|
100
|
+
"""Read an exact byte range from the target.
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
address
|
|
105
|
+
Target address to read.
|
|
106
|
+
size
|
|
107
|
+
Number of bytes to read.
|
|
108
|
+
|
|
109
|
+
Returns
|
|
110
|
+
-------
|
|
111
|
+
bytes
|
|
112
|
+
The bytes returned by the selected inferior.
|
|
113
|
+
|
|
114
|
+
Raises
|
|
115
|
+
------
|
|
116
|
+
TargetReadError
|
|
117
|
+
If GDB rejects the read or returns an incomplete range.
|
|
118
|
+
ValueError
|
|
119
|
+
If the requested range is invalid.
|
|
120
|
+
"""
|
|
121
|
+
if address < 0:
|
|
122
|
+
raise ValueError("target address must not be negative")
|
|
123
|
+
if size <= 0:
|
|
124
|
+
raise ValueError("target-memory read size must be positive")
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
result = bytes(self._inferior.read_memory(address, size))
|
|
128
|
+
except (gdb.error, gdb.MemoryError) as error:
|
|
129
|
+
raise TargetReadError(address, size, str(error)) from error
|
|
130
|
+
|
|
131
|
+
if len(result) != size:
|
|
132
|
+
raise TargetReadError(address, size, f"target returned {len(result)} byte(s)")
|
|
133
|
+
return result
|
|
134
|
+
|
|
135
|
+
def read_uint16(self, address: int) -> int:
|
|
136
|
+
"""Read a little-endian unsigned 16-bit value.
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
address
|
|
141
|
+
Target address to read.
|
|
142
|
+
|
|
143
|
+
Returns
|
|
144
|
+
-------
|
|
145
|
+
int
|
|
146
|
+
The decoded value.
|
|
147
|
+
"""
|
|
148
|
+
return int.from_bytes(self.read_bytes(address, 2), byteorder="little")
|
|
149
|
+
|
|
150
|
+
def read_uint32(self, address: int) -> int:
|
|
151
|
+
"""Read a little-endian unsigned 32-bit value.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
address
|
|
156
|
+
Target address to read.
|
|
157
|
+
|
|
158
|
+
Returns
|
|
159
|
+
-------
|
|
160
|
+
int
|
|
161
|
+
The decoded value.
|
|
162
|
+
"""
|
|
163
|
+
return int.from_bytes(self.read_bytes(address, 4), byteorder="little")
|
|
164
|
+
|
|
165
|
+
def write_uint32(self, address: int, value: int) -> None:
|
|
166
|
+
"""Write an unsigned 32-bit value to target memory in little-endian order.
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
address
|
|
171
|
+
Target address to write.
|
|
172
|
+
value
|
|
173
|
+
Unsigned 32-bit value to write.
|
|
174
|
+
|
|
175
|
+
Raises
|
|
176
|
+
------
|
|
177
|
+
TargetWriteError
|
|
178
|
+
If GDB rejects the write.
|
|
179
|
+
ValueError
|
|
180
|
+
If the target address or value is invalid.
|
|
181
|
+
"""
|
|
182
|
+
if address < 0:
|
|
183
|
+
raise ValueError("target address must not be negative")
|
|
184
|
+
if not 0 <= value <= 0xFFFFFFFF:
|
|
185
|
+
raise ValueError("target-memory write value must be an unsigned 32-bit value")
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
self._inferior.write_memory(address, value.to_bytes(4, byteorder="little"))
|
|
189
|
+
except (gdb.error, gdb.MemoryError) as error:
|
|
190
|
+
raise TargetWriteError(address, 4, str(error)) from error
|