69 lines
1.8 KiB
Python
69 lines
1.8 KiB
Python
|
#
|
||
|
# 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()
|