|
@@ -0,0 +1,68 @@
|
|
|
|
+#
|
|
|
|
+# gdb helper commands and functions for Linux kernel debugging
|
|
|
|
+#
|
|
|
|
+# per-cpu tools
|
|
|
|
+#
|
|
|
|
+# Copyright (c) Siemens AG, 2011-2013
|
|
|
|
+#
|
|
|
|
+# Authors:
|
|
|
|
+# Jan Kiszka <jan.kiszka@siemens.com>
|
|
|
|
+#
|
|
|
|
+# This work is licensed under the terms of the GNU GPL version 2.
|
|
|
|
+#
|
|
|
|
+
|
|
|
|
+import gdb
|
|
|
|
+
|
|
|
|
+from linux import tasks, utils
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+MAX_CPUS = 4096
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def get_current_cpu():
|
|
|
|
+ if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU:
|
|
|
|
+ return gdb.selected_thread().num - 1
|
|
|
|
+ elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB:
|
|
|
|
+ tid = gdb.selected_thread().ptid[2]
|
|
|
|
+ if tid > (0x100000000 - MAX_CPUS - 2):
|
|
|
|
+ return 0x100000000 - tid - 2
|
|
|
|
+ else:
|
|
|
|
+ return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu']
|
|
|
|
+ else:
|
|
|
|
+ raise gdb.GdbError("Sorry, obtaining the current CPU is not yet "
|
|
|
|
+ "supported with this gdb server.")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def per_cpu(var_ptr, cpu):
|
|
|
|
+ if cpu == -1:
|
|
|
|
+ cpu = get_current_cpu()
|
|
|
|
+ if utils.is_target_arch("sparc:v9"):
|
|
|
|
+ offset = gdb.parse_and_eval(
|
|
|
|
+ "trap_block[{0}].__per_cpu_base".format(str(cpu)))
|
|
|
|
+ else:
|
|
|
|
+ try:
|
|
|
|
+ offset = gdb.parse_and_eval(
|
|
|
|
+ "__per_cpu_offset[{0}]".format(str(cpu)))
|
|
|
|
+ except gdb.error:
|
|
|
|
+ # !CONFIG_SMP case
|
|
|
|
+ offset = 0
|
|
|
|
+ pointer = var_ptr.cast(utils.get_long_type()) + offset
|
|
|
|
+ return pointer.cast(var_ptr.type).dereference()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class PerCpu(gdb.Function):
|
|
|
|
+ """Return per-cpu variable.
|
|
|
|
+
|
|
|
|
+$lx_per_cpu("VAR"[, CPU]): Return the per-cpu variable called VAR for the
|
|
|
|
+given CPU number. If CPU is omitted, the CPU of the current context is used.
|
|
|
|
+Note that VAR has to be quoted as string."""
|
|
|
|
+
|
|
|
|
+ def __init__(self):
|
|
|
|
+ super(PerCpu, self).__init__("lx_per_cpu")
|
|
|
|
+
|
|
|
|
+ def invoke(self, var_name, cpu=-1):
|
|
|
|
+ var_ptr = gdb.parse_and_eval("&" + var_name.string())
|
|
|
|
+ return per_cpu(var_ptr, cpu)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+PerCpu()
|