summaryrefslogtreecommitdiff
path: root/scripts/gdb/linux/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/gdb/linux/utils.py')
-rw-r--r--scripts/gdb/linux/utils.py88
1 files changed, 79 insertions, 9 deletions
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
index 1553f68716cc..e11f6f67961a 100644
--- a/scripts/gdb/linux/utils.py
+++ b/scripts/gdb/linux/utils.py
@@ -11,6 +11,11 @@
# This work is licensed under the terms of the GNU GPL version 2.
#
+import contextlib
+import dataclasses
+import re
+import typing
+
import gdb
@@ -35,12 +40,32 @@ class CachedType:
long_type = CachedType("long")
+ulong_type = CachedType("unsigned long")
+uint_type = CachedType("unsigned int")
atomic_long_type = CachedType("atomic_long_t")
+size_t_type = CachedType("size_t")
+struct_page_type = CachedType("struct page")
+
+def get_uint_type():
+ global uint_type
+ return uint_type.get_type()
+
+def get_page_type():
+ global struct_page_type
+ return struct_page_type.get_type()
def get_long_type():
global long_type
return long_type.get_type()
+def get_ulong_type():
+ global ulong_type
+ return ulong_type.get_type()
+
+def get_size_t_type():
+ global size_t_type
+ return size_t_type.get_type()
+
def offset_of(typeobj, field):
element = gdb.Value(0).cast(typeobj)
return int(str(element[field].address).split()[0], 16)
@@ -88,7 +113,10 @@ def get_target_endianness():
def read_memoryview(inf, start, length):
- return memoryview(inf.read_memory(start, length))
+ m = inf.read_memory(start, length)
+ if type(m) is memoryview:
+ return m
+ return memoryview(m)
def read_u16(buffer, offset):
@@ -172,8 +200,8 @@ def get_gdbserver_type():
def probe_kgdb():
try:
- thread_info = gdb.execute("info thread 2", to_string=True)
- return "shadowCPU0" in thread_info
+ thread_info = gdb.execute("info thread 1", to_string=True)
+ return "shadowCPU" in thread_info
except gdb.error:
return False
@@ -195,9 +223,51 @@ def gdb_eval_or_none(expresssion):
return None
-def dentry_name(d):
- parent = d['d_parent']
- if parent == d or parent == 0:
- return ""
- p = dentry_name(d['d_parent']) + "/"
- return p + d['d_iname'].string()
+@contextlib.contextmanager
+def qemu_phy_mem_mode():
+ connection = gdb.selected_inferior().connection
+ orig = connection.send_packet("qqemu.PhyMemMode")
+ if orig not in b"01":
+ raise gdb.error("Unexpected qemu.PhyMemMode")
+ orig = orig.decode()
+ if connection.send_packet("Qqemu.PhyMemMode:1") != b"OK":
+ raise gdb.error("Failed to set qemu.PhyMemMode")
+ try:
+ yield
+ finally:
+ if connection.send_packet("Qqemu.PhyMemMode:" + orig) != b"OK":
+ raise gdb.error("Failed to restore qemu.PhyMemMode")
+
+
+@dataclasses.dataclass
+class VmCore:
+ kerneloffset: typing.Optional[int]
+
+
+def parse_vmcore(s):
+ match = re.search(r"KERNELOFFSET=([0-9a-f]+)", s)
+ if match is None:
+ kerneloffset = None
+ else:
+ kerneloffset = int(match.group(1), 16)
+ return VmCore(kerneloffset=kerneloffset)
+
+
+def get_vmlinux():
+ vmlinux = 'vmlinux'
+ for obj in gdb.objfiles():
+ if (obj.filename.endswith('vmlinux') or
+ obj.filename.endswith('vmlinux.debug')):
+ vmlinux = obj.filename
+ return vmlinux
+
+
+@contextlib.contextmanager
+def pagination_off():
+ show_pagination = gdb.execute("show pagination", to_string=True)
+ pagination = show_pagination.endswith("on.\n")
+ gdb.execute("set pagination off")
+ try:
+ yield
+ finally:
+ gdb.execute("set pagination %s" % ("on" if pagination else "off"))