emdbg.debug.px4.base

  1# Copyright (c) 2023, Auterion AG
  2# SPDX-License-Identifier: BSD-3-Clause
  3
  4from __future__ import annotations
  5import re
  6from . import utils
  7from functools import cached_property
  8
  9class Base:
 10    """
 11    This base class provides basic abstractions to simplify usage of the GDB
 12    Python API, which can be a little verbose.
 13
 14    It also provides a mechanism to invalidate cached properties whenever GDB
 15    stopped. This allows the use of `@cached_property` when the target is halted
 16    to cache expensive operations.
 17    """
 18    def __init__(self, gdb):
 19        self._gdb = gdb
 20        self._inf = gdb.selected_inferior()
 21        self._arch = self._inf.architecture()
 22        self.register_names = [r.name for r in self._arch.registers()]
 23        # Registering a callback for every obj makes GDB *really* slow :(
 24        global _CACHED_OBJECTS
 25        if _CACHED_OBJECTS is None:
 26            gdb.events.stop.connect(_invalidate_cached_properties)
 27            _CACHED_OBJECTS = []
 28        _CACHED_OBJECTS.append(self)
 29
 30    def _invalidate(self):
 31        for key, value in self.__class__.__dict__.items():
 32            if isinstance(value, cached_property):
 33                self.__dict__.pop(key, None)
 34
 35    @cached_property
 36    def registers(self) -> dict[str, int]:
 37        """All register names and unsigned values in the selected frame."""
 38        return {r: self.read_register(r) for r in self.register_names}
 39
 40    def read_register(self, name: str) -> int:
 41        """:return: unsigned value of the named register in the selected frame"""
 42        frame = self._gdb.selected_frame()
 43        # This is convoluted because we need to get the raw FPU register values!
 44        # Otherwise they get cast from double to int, which is wrong.
 45        value = int(frame.read_register(name).format_string(format="x"), 16)
 46        return value
 47
 48    def write_register(self, name: str, value: int):
 49        """Writes a value into the named register"""
 50        try:
 51            # casting to (void*) allows setting the FPU registers with raw!
 52            self._gdb.execute(f"set ${name} = (void*){int(value):#x}")
 53        except Exception as e:
 54            print(e)
 55
 56    def write_registers(self, values: dict[str, int]):
 57        """Writes all named registers into the CPU"""
 58        for name, value in values.items():
 59            if name in ["control", "faultmask", "primask"]: continue
 60            # GDB does not know SP, only MSP and PSP
 61            if name in ["sp", "r13"]:
 62                name = "msp"
 63            if name == "msp":
 64                self.write_register("r13", value)
 65            # Remove double FP registers
 66            if name.startswith("d"): continue
 67            self.write_register(name, value)
 68
 69    def fix_nuttx_sp(self, regs: dict[str, int]):
 70        """Fixes stored SP, as NuttX incorrectly stores the SP (is off by 4 bytes)"""
 71        regs["msp"] = regs["msp"] + 4
 72        regs["sp"] = regs["msp"]
 73        regs["r13"] = regs["msp"]
 74        return regs
 75
 76    def lookup_static_symbol_in_function(self, symbol_name: str, function_name: str) -> "gdb.Symbol | None":
 77        """
 78        Lookup a static symbol inside a function. GDB makes this complicated
 79        since static symbols inside functions are not accessible directly.
 80
 81        :return: the symbol if found or `None`
 82        """
 83        if (function := self._gdb.lookup_global_symbol(function_name)) is None:
 84            return None
 85        function = function.value()
 86        function_block = self._gdb.block_for_pc(int(function.address))
 87        for symbol in function_block:
 88            if symbol.addr_class == self._gdb.SYMBOL_LOC_STATIC:
 89                if symbol.name == symbol_name:
 90                    return symbol
 91        return None
 92
 93    def lookup_static_symbol_ptr(self, name: str) -> "gdb.Value":
 94        """:return: a Value to a static symbol name"""
 95        if symbol := self._gdb.lookup_static_symbol(name):
 96            return self.value_ptr(symbol)
 97        return None
 98
 99    def lookup_global_symbol_ptr(self, name) -> "gdb.Value":
100        """:return: a Value to a global symbol name"""
101        if symbol := self._gdb.lookup_global_symbol(name):
102            return self.value_ptr(symbol)
103        return None
104
105    def lookup_static_symbol_in_function_ptr(self, symbol_name: str, function_name: str) -> "gdb.Value | None":
106        """:return: a Value to a global symbol name"""
107        if symbol := self.lookup_static_symbol_in_function(symbol_name, function_name):
108            return self.value_ptr(symbol)
109        return None
110
111    def value_ptr(self, symbol: "gdb.Symbol") -> "gdb.Value":
112        """
113        Convert a symbol into a value. This can be useful if you want to keep a
114        "pointer" of the symbol, whose content is always up-to-date, rather than
115        a local copy, which will never be updated again.
116        """
117        return self._gdb.Value(symbol.value().address).cast(symbol.type.pointer())
118
119    def addr_ptr(self, addr: int, type: str) -> "gdb.Value":
120        """Cast a memory address to a custom type."""
121        return self._gdb.Value(addr).cast(self._gdb.lookup_type(type).pointer())
122
123    def read_memory(self, address: int, size: int) -> memoryview:
124        """
125        Reads a block of memory and returns its content.
126        See [Inferiors](https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-In-Python.html).
127        """
128        return self._inf.read_memory(address, size)
129
130    def write_memory(self, address: int, buffer, length: int):
131        """
132        Writes a block of memory to an address.
133        See [Inferiors](https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-In-Python.html).
134        """
135        self._inf.write_memory(address, buffer, length=length)
136
137    def read_uint(self, addr: int, size: int, default=None) -> int:
138        """Reads an unsigned integer from a memory address"""
139        if (itype := {1: "B", 2: "H", 4: "I", 8: "Q"}.get(size)) is None:
140            raise ValueError("Unsupported unsigned integer size!")
141        try:
142            return self.read_memory(addr, size).cast(itype)[0]
143        except self._gdb.MemoryError:
144            return default
145
146    def read_int(self, addr: int, size: int, default=None) -> int:
147        """Reads a signed integer from a memory address"""
148        if (itype := {1: "b", 2: "h", 4: "i", 8: "q"}.get(size)) is None:
149            raise ValueError("Unsupported signed integer size!")
150        try:
151            return self.read_memory(addr, size).cast(itype)[0]
152        except self._gdb.MemoryError:
153            return default
154
155    def read_string(self, addr: int, encoding: str = None,
156                    errors: str = None, length: int = None) -> str:
157        """Reads a string of a fixed length, or with 0 termination"""
158        kwargs = {"encoding": encoding or "ascii", "errors": errors or "ignore"}
159        if length: kwargs["length"] = length
160        return self.addr_ptr(addr, "char").string(**kwargs)
161
162    def symtab_line(self, pc: int) -> "gdb.Symtab_and_line":
163        """:return: the symbol table and line for a program location"""
164        return self._gdb.find_pc_line(int(pc))
165
166    def block(self, pc: int) -> "gdb.Block":
167        """:return: the block for a program location"""
168        return self._gdb.block_for_pc(int(pc))
169
170    def description_at(self, addr: int) -> str | None:
171        """:return: the human-readable symbol description at an address"""
172        output = self._gdb.execute(f"info symbol *{int(addr)}", to_string=True)
173        if match := re.search(r"(.*?) in section (.*?)", output):
174            return match.group(1)
175        return None
176
177    def integer_type(self, size: int, signed: bool = True) -> "gdb.Type":
178        """:return: The built-in integer type for the size in bits"""
179        return self._arch.integer_type(size * 8, signed=True)
180
181    @property
182    def uint32(self) -> "gdb.Type":
183        """The built-in unsigned 32-bit integer type"""
184        return self.integer_type(4, False)
185
186    @property
187    def int32(self) -> "gdb.Type":
188        """The built-in signed 32-bit integer type"""
189        return self.integer_type(4, True)
190
191
192# Single callback makes GDB much faster, so we do the loop ourselves
193_CACHED_OBJECTS = None
194def _invalidate_cached_properties(event):
195    global _CACHED_OBJECTS
196    for obj in _CACHED_OBJECTS:
197        if obj: obj._invalidate()
class Base:
 10class Base:
 11    """
 12    This base class provides basic abstractions to simplify usage of the GDB
 13    Python API, which can be a little verbose.
 14
 15    It also provides a mechanism to invalidate cached properties whenever GDB
 16    stopped. This allows the use of `@cached_property` when the target is halted
 17    to cache expensive operations.
 18    """
 19    def __init__(self, gdb):
 20        self._gdb = gdb
 21        self._inf = gdb.selected_inferior()
 22        self._arch = self._inf.architecture()
 23        self.register_names = [r.name for r in self._arch.registers()]
 24        # Registering a callback for every obj makes GDB *really* slow :(
 25        global _CACHED_OBJECTS
 26        if _CACHED_OBJECTS is None:
 27            gdb.events.stop.connect(_invalidate_cached_properties)
 28            _CACHED_OBJECTS = []
 29        _CACHED_OBJECTS.append(self)
 30
 31    def _invalidate(self):
 32        for key, value in self.__class__.__dict__.items():
 33            if isinstance(value, cached_property):
 34                self.__dict__.pop(key, None)
 35
 36    @cached_property
 37    def registers(self) -> dict[str, int]:
 38        """All register names and unsigned values in the selected frame."""
 39        return {r: self.read_register(r) for r in self.register_names}
 40
 41    def read_register(self, name: str) -> int:
 42        """:return: unsigned value of the named register in the selected frame"""
 43        frame = self._gdb.selected_frame()
 44        # This is convoluted because we need to get the raw FPU register values!
 45        # Otherwise they get cast from double to int, which is wrong.
 46        value = int(frame.read_register(name).format_string(format="x"), 16)
 47        return value
 48
 49    def write_register(self, name: str, value: int):
 50        """Writes a value into the named register"""
 51        try:
 52            # casting to (void*) allows setting the FPU registers with raw!
 53            self._gdb.execute(f"set ${name} = (void*){int(value):#x}")
 54        except Exception as e:
 55            print(e)
 56
 57    def write_registers(self, values: dict[str, int]):
 58        """Writes all named registers into the CPU"""
 59        for name, value in values.items():
 60            if name in ["control", "faultmask", "primask"]: continue
 61            # GDB does not know SP, only MSP and PSP
 62            if name in ["sp", "r13"]:
 63                name = "msp"
 64            if name == "msp":
 65                self.write_register("r13", value)
 66            # Remove double FP registers
 67            if name.startswith("d"): continue
 68            self.write_register(name, value)
 69
 70    def fix_nuttx_sp(self, regs: dict[str, int]):
 71        """Fixes stored SP, as NuttX incorrectly stores the SP (is off by 4 bytes)"""
 72        regs["msp"] = regs["msp"] + 4
 73        regs["sp"] = regs["msp"]
 74        regs["r13"] = regs["msp"]
 75        return regs
 76
 77    def lookup_static_symbol_in_function(self, symbol_name: str, function_name: str) -> "gdb.Symbol | None":
 78        """
 79        Lookup a static symbol inside a function. GDB makes this complicated
 80        since static symbols inside functions are not accessible directly.
 81
 82        :return: the symbol if found or `None`
 83        """
 84        if (function := self._gdb.lookup_global_symbol(function_name)) is None:
 85            return None
 86        function = function.value()
 87        function_block = self._gdb.block_for_pc(int(function.address))
 88        for symbol in function_block:
 89            if symbol.addr_class == self._gdb.SYMBOL_LOC_STATIC:
 90                if symbol.name == symbol_name:
 91                    return symbol
 92        return None
 93
 94    def lookup_static_symbol_ptr(self, name: str) -> "gdb.Value":
 95        """:return: a Value to a static symbol name"""
 96        if symbol := self._gdb.lookup_static_symbol(name):
 97            return self.value_ptr(symbol)
 98        return None
 99
100    def lookup_global_symbol_ptr(self, name) -> "gdb.Value":
101        """:return: a Value to a global symbol name"""
102        if symbol := self._gdb.lookup_global_symbol(name):
103            return self.value_ptr(symbol)
104        return None
105
106    def lookup_static_symbol_in_function_ptr(self, symbol_name: str, function_name: str) -> "gdb.Value | None":
107        """:return: a Value to a global symbol name"""
108        if symbol := self.lookup_static_symbol_in_function(symbol_name, function_name):
109            return self.value_ptr(symbol)
110        return None
111
112    def value_ptr(self, symbol: "gdb.Symbol") -> "gdb.Value":
113        """
114        Convert a symbol into a value. This can be useful if you want to keep a
115        "pointer" of the symbol, whose content is always up-to-date, rather than
116        a local copy, which will never be updated again.
117        """
118        return self._gdb.Value(symbol.value().address).cast(symbol.type.pointer())
119
120    def addr_ptr(self, addr: int, type: str) -> "gdb.Value":
121        """Cast a memory address to a custom type."""
122        return self._gdb.Value(addr).cast(self._gdb.lookup_type(type).pointer())
123
124    def read_memory(self, address: int, size: int) -> memoryview:
125        """
126        Reads a block of memory and returns its content.
127        See [Inferiors](https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-In-Python.html).
128        """
129        return self._inf.read_memory(address, size)
130
131    def write_memory(self, address: int, buffer, length: int):
132        """
133        Writes a block of memory to an address.
134        See [Inferiors](https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-In-Python.html).
135        """
136        self._inf.write_memory(address, buffer, length=length)
137
138    def read_uint(self, addr: int, size: int, default=None) -> int:
139        """Reads an unsigned integer from a memory address"""
140        if (itype := {1: "B", 2: "H", 4: "I", 8: "Q"}.get(size)) is None:
141            raise ValueError("Unsupported unsigned integer size!")
142        try:
143            return self.read_memory(addr, size).cast(itype)[0]
144        except self._gdb.MemoryError:
145            return default
146
147    def read_int(self, addr: int, size: int, default=None) -> int:
148        """Reads a signed integer from a memory address"""
149        if (itype := {1: "b", 2: "h", 4: "i", 8: "q"}.get(size)) is None:
150            raise ValueError("Unsupported signed integer size!")
151        try:
152            return self.read_memory(addr, size).cast(itype)[0]
153        except self._gdb.MemoryError:
154            return default
155
156    def read_string(self, addr: int, encoding: str = None,
157                    errors: str = None, length: int = None) -> str:
158        """Reads a string of a fixed length, or with 0 termination"""
159        kwargs = {"encoding": encoding or "ascii", "errors": errors or "ignore"}
160        if length: kwargs["length"] = length
161        return self.addr_ptr(addr, "char").string(**kwargs)
162
163    def symtab_line(self, pc: int) -> "gdb.Symtab_and_line":
164        """:return: the symbol table and line for a program location"""
165        return self._gdb.find_pc_line(int(pc))
166
167    def block(self, pc: int) -> "gdb.Block":
168        """:return: the block for a program location"""
169        return self._gdb.block_for_pc(int(pc))
170
171    def description_at(self, addr: int) -> str | None:
172        """:return: the human-readable symbol description at an address"""
173        output = self._gdb.execute(f"info symbol *{int(addr)}", to_string=True)
174        if match := re.search(r"(.*?) in section (.*?)", output):
175            return match.group(1)
176        return None
177
178    def integer_type(self, size: int, signed: bool = True) -> "gdb.Type":
179        """:return: The built-in integer type for the size in bits"""
180        return self._arch.integer_type(size * 8, signed=True)
181
182    @property
183    def uint32(self) -> "gdb.Type":
184        """The built-in unsigned 32-bit integer type"""
185        return self.integer_type(4, False)
186
187    @property
188    def int32(self) -> "gdb.Type":
189        """The built-in signed 32-bit integer type"""
190        return self.integer_type(4, True)

This base class provides basic abstractions to simplify usage of the GDB Python API, which can be a little verbose.

It also provides a mechanism to invalidate cached properties whenever GDB stopped. This allows the use of @cached_property when the target is halted to cache expensive operations.

Base(gdb)
19    def __init__(self, gdb):
20        self._gdb = gdb
21        self._inf = gdb.selected_inferior()
22        self._arch = self._inf.architecture()
23        self.register_names = [r.name for r in self._arch.registers()]
24        # Registering a callback for every obj makes GDB *really* slow :(
25        global _CACHED_OBJECTS
26        if _CACHED_OBJECTS is None:
27            gdb.events.stop.connect(_invalidate_cached_properties)
28            _CACHED_OBJECTS = []
29        _CACHED_OBJECTS.append(self)
register_names
registers: dict[str, int]
36    @cached_property
37    def registers(self) -> dict[str, int]:
38        """All register names and unsigned values in the selected frame."""
39        return {r: self.read_register(r) for r in self.register_names}

All register names and unsigned values in the selected frame.

def read_register(self, name: str) -> int:
41    def read_register(self, name: str) -> int:
42        """:return: unsigned value of the named register in the selected frame"""
43        frame = self._gdb.selected_frame()
44        # This is convoluted because we need to get the raw FPU register values!
45        # Otherwise they get cast from double to int, which is wrong.
46        value = int(frame.read_register(name).format_string(format="x"), 16)
47        return value
Returns

unsigned value of the named register in the selected frame

def write_register(self, name: str, value: int):
49    def write_register(self, name: str, value: int):
50        """Writes a value into the named register"""
51        try:
52            # casting to (void*) allows setting the FPU registers with raw!
53            self._gdb.execute(f"set ${name} = (void*){int(value):#x}")
54        except Exception as e:
55            print(e)

Writes a value into the named register

def write_registers(self, values: dict[str, int]):
57    def write_registers(self, values: dict[str, int]):
58        """Writes all named registers into the CPU"""
59        for name, value in values.items():
60            if name in ["control", "faultmask", "primask"]: continue
61            # GDB does not know SP, only MSP and PSP
62            if name in ["sp", "r13"]:
63                name = "msp"
64            if name == "msp":
65                self.write_register("r13", value)
66            # Remove double FP registers
67            if name.startswith("d"): continue
68            self.write_register(name, value)

Writes all named registers into the CPU

def fix_nuttx_sp(self, regs: dict[str, int]):
70    def fix_nuttx_sp(self, regs: dict[str, int]):
71        """Fixes stored SP, as NuttX incorrectly stores the SP (is off by 4 bytes)"""
72        regs["msp"] = regs["msp"] + 4
73        regs["sp"] = regs["msp"]
74        regs["r13"] = regs["msp"]
75        return regs

Fixes stored SP, as NuttX incorrectly stores the SP (is off by 4 bytes)

def lookup_static_symbol_in_function(self, symbol_name: str, function_name: str) -> "'gdb.Symbol | None'":
77    def lookup_static_symbol_in_function(self, symbol_name: str, function_name: str) -> "gdb.Symbol | None":
78        """
79        Lookup a static symbol inside a function. GDB makes this complicated
80        since static symbols inside functions are not accessible directly.
81
82        :return: the symbol if found or `None`
83        """
84        if (function := self._gdb.lookup_global_symbol(function_name)) is None:
85            return None
86        function = function.value()
87        function_block = self._gdb.block_for_pc(int(function.address))
88        for symbol in function_block:
89            if symbol.addr_class == self._gdb.SYMBOL_LOC_STATIC:
90                if symbol.name == symbol_name:
91                    return symbol
92        return None

Lookup a static symbol inside a function. GDB makes this complicated since static symbols inside functions are not accessible directly.

Returns

the symbol if found or None

def lookup_static_symbol_ptr(self, name: str) -> "'gdb.Value'":
94    def lookup_static_symbol_ptr(self, name: str) -> "gdb.Value":
95        """:return: a Value to a static symbol name"""
96        if symbol := self._gdb.lookup_static_symbol(name):
97            return self.value_ptr(symbol)
98        return None
Returns

a Value to a static symbol name

def lookup_global_symbol_ptr(self, name) -> "'gdb.Value'":
100    def lookup_global_symbol_ptr(self, name) -> "gdb.Value":
101        """:return: a Value to a global symbol name"""
102        if symbol := self._gdb.lookup_global_symbol(name):
103            return self.value_ptr(symbol)
104        return None
Returns

a Value to a global symbol name

def lookup_static_symbol_in_function_ptr(self, symbol_name: str, function_name: str) -> "'gdb.Value | None'":
106    def lookup_static_symbol_in_function_ptr(self, symbol_name: str, function_name: str) -> "gdb.Value | None":
107        """:return: a Value to a global symbol name"""
108        if symbol := self.lookup_static_symbol_in_function(symbol_name, function_name):
109            return self.value_ptr(symbol)
110        return None
Returns

a Value to a global symbol name

def value_ptr(self, symbol: "'gdb.Symbol'") -> "'gdb.Value'":
112    def value_ptr(self, symbol: "gdb.Symbol") -> "gdb.Value":
113        """
114        Convert a symbol into a value. This can be useful if you want to keep a
115        "pointer" of the symbol, whose content is always up-to-date, rather than
116        a local copy, which will never be updated again.
117        """
118        return self._gdb.Value(symbol.value().address).cast(symbol.type.pointer())

Convert a symbol into a value. This can be useful if you want to keep a "pointer" of the symbol, whose content is always up-to-date, rather than a local copy, which will never be updated again.

def addr_ptr(self, addr: int, type: str) -> "'gdb.Value'":
120    def addr_ptr(self, addr: int, type: str) -> "gdb.Value":
121        """Cast a memory address to a custom type."""
122        return self._gdb.Value(addr).cast(self._gdb.lookup_type(type).pointer())

Cast a memory address to a custom type.

def read_memory(self, address: int, size: int) -> memoryview:
124    def read_memory(self, address: int, size: int) -> memoryview:
125        """
126        Reads a block of memory and returns its content.
127        See [Inferiors](https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-In-Python.html).
128        """
129        return self._inf.read_memory(address, size)

Reads a block of memory and returns its content. See Inferiors.

def write_memory(self, address: int, buffer, length: int):
131    def write_memory(self, address: int, buffer, length: int):
132        """
133        Writes a block of memory to an address.
134        See [Inferiors](https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-In-Python.html).
135        """
136        self._inf.write_memory(address, buffer, length=length)

Writes a block of memory to an address. See Inferiors.

def read_uint(self, addr: int, size: int, default=None) -> int:
138    def read_uint(self, addr: int, size: int, default=None) -> int:
139        """Reads an unsigned integer from a memory address"""
140        if (itype := {1: "B", 2: "H", 4: "I", 8: "Q"}.get(size)) is None:
141            raise ValueError("Unsupported unsigned integer size!")
142        try:
143            return self.read_memory(addr, size).cast(itype)[0]
144        except self._gdb.MemoryError:
145            return default

Reads an unsigned integer from a memory address

def read_int(self, addr: int, size: int, default=None) -> int:
147    def read_int(self, addr: int, size: int, default=None) -> int:
148        """Reads a signed integer from a memory address"""
149        if (itype := {1: "b", 2: "h", 4: "i", 8: "q"}.get(size)) is None:
150            raise ValueError("Unsupported signed integer size!")
151        try:
152            return self.read_memory(addr, size).cast(itype)[0]
153        except self._gdb.MemoryError:
154            return default

Reads a signed integer from a memory address

def read_string( self, addr: int, encoding: str = None, errors: str = None, length: int = None) -> str:
156    def read_string(self, addr: int, encoding: str = None,
157                    errors: str = None, length: int = None) -> str:
158        """Reads a string of a fixed length, or with 0 termination"""
159        kwargs = {"encoding": encoding or "ascii", "errors": errors or "ignore"}
160        if length: kwargs["length"] = length
161        return self.addr_ptr(addr, "char").string(**kwargs)

Reads a string of a fixed length, or with 0 termination

def symtab_line(self, pc: int) -> "'gdb.Symtab_and_line'":
163    def symtab_line(self, pc: int) -> "gdb.Symtab_and_line":
164        """:return: the symbol table and line for a program location"""
165        return self._gdb.find_pc_line(int(pc))
Returns

the symbol table and line for a program location

def block(self, pc: int) -> "'gdb.Block'":
167    def block(self, pc: int) -> "gdb.Block":
168        """:return: the block for a program location"""
169        return self._gdb.block_for_pc(int(pc))
Returns

the block for a program location

def description_at(self, addr: int) -> str | None:
171    def description_at(self, addr: int) -> str | None:
172        """:return: the human-readable symbol description at an address"""
173        output = self._gdb.execute(f"info symbol *{int(addr)}", to_string=True)
174        if match := re.search(r"(.*?) in section (.*?)", output):
175            return match.group(1)
176        return None
Returns

the human-readable symbol description at an address

def integer_type(self, size: int, signed: bool = True) -> "'gdb.Type'":
178    def integer_type(self, size: int, signed: bool = True) -> "gdb.Type":
179        """:return: The built-in integer type for the size in bits"""
180        return self._arch.integer_type(size * 8, signed=True)
Returns

The built-in integer type for the size in bits

uint32: "'gdb.Type'"
182    @property
183    def uint32(self) -> "gdb.Type":
184        """The built-in unsigned 32-bit integer type"""
185        return self.integer_type(4, False)

The built-in unsigned 32-bit integer type

int32: "'gdb.Type'"
187    @property
188    def int32(self) -> "gdb.Type":
189        """The built-in signed 32-bit integer type"""
190        return self.integer_type(4, True)

The built-in signed 32-bit integer type